package com.jnc.pay.core.vertx;

import com.jnc.pay.core.exception.IdempotencyException;
import com.jnc.pay.core.exception.LockException;
import com.jnc.pay.core.model.BaseResp;
import com.jnc.pay.core.model.RespCode;
import com.jnc.pay.core.vertx.filter.PreHandler;
import com.jnc.pay.util.convert.JsonUtil;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * @Author: jjn
 * @Date: 2019/2/25 15:31
 * @Desc: vert.x程序的入口
 */
@Slf4j
@Configuration
public class AdviceHttpServer {
    /**
     * HttpServer配置：项目启动已初始化，此时自动注入
     */
    @Autowired
    private HttpServerOptions options;
    private HttpServer httpServer;  //http服务端
    @Autowired
    private Vertx vertx;
    @Autowired
    private PreHandler preHandler;

    @Bean
    public Router getRouter(){
        Router router = Router.router(vertx);
        return router;
    }

    /**
     * 优先级：构造方法 > @Autowired > @PostConstruct
     */
    @PostConstruct
    public void creatHttpServer(){
        Router router = getRouter();
        router.route().handler(BodyHandler.create()
                .setBodyLimit(options.getReceiveBufferSize() * 1024));

        //添加拦截器
        router.route().path("/v1/biz/*").handler(preHandler);
        //统一异常
        router.route().failureHandler(routingContext -> {
            HttpServerResponse response = routingContext.request().response();
            BaseResp resp = new BaseResp();
            Throwable throwable = routingContext.failure();
            if(throwable instanceof LockException){
                resp.setCode(RespCode.ERROR.getCode()).setMsg(throwable.getMessage());
            }else if(throwable instanceof IdempotencyException){
                resp.setCode(RespCode.ERROR.getCode()).setMsg(throwable.getMessage());
            }else{
                resp.setCode(RespCode.ERROR.getCode()).setMsg("Internal Server Error");
                log.error("Internal server error: {}", routingContext.failure());
            }
            response.end(JsonUtil.bean2Json(resp));
        });
        //监听port
        httpServer = vertx.createHttpServer(options);
        httpServer.requestHandler(router).listen(options.getPort(), handler ->{
            if (handler.succeeded()){
                log.debug("vertx router http server start successful");
            }else{
                log.debug("vertx router http server start fail");
            }
        });
    }
}
